<!-- 你问我答详情页 -->
<template>
  <!-- 顶部框 -->
  <div class="w-screen-calc" style="height: 100px;">
    <div class="fixed top-0 left-0 z-5 w-full pt-1" style=" background-color: #eeeeee;">
      <div class="grid">
        <div class="col-2 text-center">
          <Image style="cursor: pointer;"
                 alt="网站图标"
                 src="https://img.yeziji.xyz/mobile/logger/forum-mobile.png"
                 :width="140"
                 @click="toHome()"/>
        </div>
        <div class="col-10 align-self-center flex align-items-center" style="justify-content: right !important;">
          <Button id="editDetailBtn"
                  v-if="showEditor"
                  class="mr-5 p-button-raised p-button-text"
                  icon="pi pi-pencil"
                  label="我要提问"
                  @click="openEditorHandler(1)"/>
          <UserButton/>
        </div>
      </div>
    </div>
  </div>
  <!-- 内容 -->
  <div class="grid" ref="qaContainer">
    <!-- 左侧导航栏 -->
    <div class="col-2">
      <StickyPanel top="40px" class="mt-4" :dom="qaContainer">
        <template #content>
          <LeftMenu/>
        </template>
      </StickyPanel>
    </div>
    <!-- 内容 -->
    <div class="col-10 p-3" :key="containerKey">
      <!-- 问题与回答 -->
      <div class="grid qa__container p-5">
        <!-- ---------------- 问题专区 ---------------- -->
        <!-- 标题信息内容 -->
        <div class="qa__info">
          <!-- 标题 -->
          <div class="col-12 qa__title">
            {{ questionDetail?.title }}
          </div>
          <!-- 提问信息 -->
          <div class="col-12 flex border-bottom-1 border-300">
            <span class="qa__update_time">
              <span class="qa__label">
                创建时间
              </span>
              {{ questionDetail?.createTime }}
          </span>
            <span class="qa__update_time">
              <span class="qa__label">
                最后修改时间
              </span>
              {{ questionDetail?.updateTime }}
          </span>
            <span class="qa__update_time">
              <span class="qa__label">
                查看人数
              </span>
              {{ questionDetail?.viewNumber }}
          </span>
          </div>
        </div>
        <!-- 提问内容 -->
        <div class="col-12 qa__content question__container border-300 pb-5">
          <MdPreviewPanel :markdown="questionDetail?.content"/>
        </div>
        <!-- 发起回答的按钮 -->
        <div v-if="!questionDetail?.resolve" class="col-12 flex justify-content-end align-items-end mt-5">
          <Button label="我来回答" @click="openEditorHandler(0)"></Button>
        </div>
        <!-- ---------------- 答案专区 ---------------- -->
        <div class="grid col-12">
          <div class="col-12">
            <div class="qa__title" style="font-family: Segoe Print,serif; font-width: 300 ;">
              <span class="text-red-600">
                ({{ questionDetail?.answerNumber }})
              </span>
              Answer
            </div>
          </div>
          <!-- 用户答案 -->
          <div v-for="(item, index) of answers" class="col-12" :key="item.id + '-' + index">
            <!-- 回答内容 -->
            <div class="col-12 answer__container w-screen-calc">
              <!-- fixme: 没有做md -->
              <MdPreviewPanel :markdown="item.content"/>
            </div>
            <!-- 回答者的信息 -->
            <div class="col-12 grid flex answer__info border-bottom-1 border-300">
              <!-- 回答时间 -->
              <div class="col-12 flex flex-grow-1 justify-content-end align-items-end align-content-end"
                   style="padding: 10px 5px 1px 5px;">
            <span class="qa__update_time" style="margin-bottom: 0 !important;">
              <span class="qa__label">
                回答时间
              </span>
              {{ item.updateTime ? item.updateTime : item.createTime }}
            </span>
              </div>
              <!-- action -->
              <div class="col-6 flex justify-content-start align-items-center align-content-center">
                <div class="flex qa__update_time align-content-center align-items-center">
                  <div class="qa__question__name ml-2">
                    <a href="javascript:" @click="mainReply(item.id, item.nickname)">回复</a>
                  </div>
                </div>
                <BlockageButton @non-blockage-function="kudosAction"
                                @blockage-function="(time) => toast.error('等等..等等啊~~', `太快了太快了，请${(time / 1000).toFixed(2)}秒后重试。🤬`, 1500)"
                                :exec-data="{index: index, id: item.id}"
                                child :blockage-time="2000">
                  <template #container>
                    <div class="flex qa__update_time align-content-center align-items-center">
                      <div class="qa__question__name ml-2">
                        <a href="javascript:">点赞 ({{
                            item.goodNumber
                          }})</a>
                      </div>
                    </div>
                  </template>
                </BlockageButton>

              </div>
              <!-- 回答用户昵称 -->
              <div class="col-6 flex justify-content-end align-items-center align-content-center">
                <div class="flex qa__update_time align-content-center align-items-center">
                  <ImgTextAvatar size="normal"
                                 :label="item.nickname"
                                 :image="item.avatar"/>
                  <div class="qa__question__name ml-2">
                    <a href="javascript:">{{ item.nickname }}</a>
                  </div>
                </div>
              </div>
            </div>
            <!-- 评论回复者的内容 -->
            <div class="col-12 reply__container border-bottom-1 border-300"
                 v-for="(child, cindex) of item.child"
                 :key="child.id +'-'+cindex">
              <span v-if="cindex !== 0 && child.atNickname !== child.nickname"
                    class="reply__at">
                <a href="javascript">@{{ child.atNickname }}:</a>
              </span>
              {{ child.content }}
              <span class="reply__author">
              –  <a href="javascript:" class="reply__author__link">{{ child.nickname }}</a>
            </span>
              <span class="reply__time qa__label">
              {{ child.updateTime ? child.updateTime : child.createTime }}
            </span>
              <span class="reply__action" @click="mainReply(child.id, child.nickname)">
                <svg width="12" height="12" viewBox="0 0 2048 2048">
                  <path
                      d="M1152 640q128 0 245 48t208 139q91 91 139 208t48 245q0 133-50 249t-137 204t-203 137t-250 50v-128q106 0 199-40t162-110t110-163t41-199q0-106-40-199t-110-162t-163-110t-199-41H475l402 403l-90 90l-557-557l557-557l90 90l-402 403h677z"/>
                </svg>
                回复
              </span>
            </div>
          </div>
        </div>
      </div>
    </div>
  </div>
  <!-- 编辑器弹框 -->
  <EditorDialog max-weight="80vw"
                :input-default-value="submitInfo.title"
                :editor-default-value="submitInfo.content"
                :show="openEditor"
                :show-input="openMode === 1"
                :editor-place-holder="`${openMode === 1 ? '请描述你的问题' : '请阐述你的观点'}`"
                @close="editorCloseHandler"
                @editor-change="editorChangeHandler"
                @input-change="inputChangeHandler"
                @test-value="editorTestValueHandler"
                text-placeholder="请简要概括你的问题">
    <template #footer>
      <div class="flex justify-content-end">
        <Button @click="openMode === 0 ?  replyQuestion() : submitQuestion()"
                :label="`${openMode === 0 ? '回答' : '提问'}`"></Button>
      </div>
    </template>
  </EditorDialog>

  <!-- 文本回复弹框 -->
  <Dialog v-model:visible="replyDialog" position="top">
    <template #header>
      <h4>回复: {{ atUser }}</h4>
    </template>
    <Textarea style="resize: none !important; width: 50vw; padding: 10px; margin: 5px;"
              class="col-12"
              v-model="replyText"
              rows="5" cols="30"
              placeholder="写入你要回复的内容"></Textarea>
    <template #footer>
      <Button label="回复" @click="replyAnswer"></Button>
    </template>
  </Dialog>
</template>

<script lang="ts" setup>
/** JS */
import {ref, Ref, reactive, watch, onMounted} from 'vue';
import {useRouter, useRoute} from 'vue-router';
import Cache from '@/utils/Cache';
import {
  QuestionService,
  AnswerService,
  AnswerResponse,
  QuestionInfo,
  AnswerReply,
  QuestionResponse, ReplyMode
} from '@/utils/ApiRequest';
import {ExecFunction} from '@/utils/YzjUtils';
import {encrypt, decrypt} from '@/utils/PakoUtils';
import {ProcessingData} from '@/utils/YzjUtils';
import toast from '@/utils/Toast';
import {useConfirm} from 'primevue/useconfirm';
/** 组件 */
import UserButton from '@/components/button/UserButton.vue';
import LeftMenu from '@/components/menu/LeftMenu.vue';
import EditorDialog from '@/components/editor/Dialog/EditorDialog.vue';
import StickyPanel from '@/components/panel/StickyPanel.vue';
import ImgTextAvatar from '@/components/avatar/ImgTextAvatar.vue';
import Dialog from 'primevue/dialog';
import MdPreviewPanel from '@/components/panel/MdPreviewPanel.vue';
import BlockageButton from '@/components/button/BlockageButton.vue';

// 必须要有参数 id，否则返回上一页。
const router = useRouter(),
    route = useRoute(),
    cache = new Cache(),
    userMsg = cache.get('userMsg'),
    questionService = new QuestionService(),
    answerService = new AnswerService(),
    dataUtils = new ProcessingData(),
    {id} = route.params,
    containerKey = ref(0),
    execFunction = new ExecFunction();
if (!id) {
  router.back();
}

function validate() {
  if (!userMsg) {
    toast.warn('不行的哟', `必须要先登录之后才能参与讨论哦！~(●'◡'●)`, 1500);
    return false;
  }
  return true;
}

/** 元素钩子 */
const qaContainer = ref(null);
/** 获取提问内容 */
const questionDetail: Ref<QuestionResponse | undefined> = ref<QuestionResponse>();
const getQuestionDetail = async () => {
  let res = await questionService.get(id as string);
  if (res) {
    document.title = `${res.data.resolve ? '已解决【' : '未解决【'}${res.data.title}】`;
    questionDetail.value = res.data;
    questionDetail.value.content = decodeURIComponent(decrypt(res.data.content));
  }
  await getAnswerList();
}
/** 获取答案列表 */
const answers: Ref<AnswerResponse[]> = ref([]), replyId = ref(0);
const getAnswerList = async () => {
  let res = await answerService.list(id as string);
  if (res && res.code === 0) {
    answers.value = res.data.map(answer => {
      answer.content = decodeURIComponent(decrypt(answer.content));
      if (answer.child && answer.child.length > 0) {
        answer.child.forEach(child => {
          child.content = decodeURIComponent(decrypt(child.content));
        })
      }
      return answer;
    })
  }
};

onMounted(() => {
  getQuestionDetail();
})

/* TODO =============== 重复代码用于布局，后续提取重构 =============== */
/** 返回主页面 */
const toHome = () => {
  router.push({
    path: '/',
  });
};
/** 提问编辑器处理 */
const openEditor = ref(false),
    showEditor = ref(userMsg !== undefined),
    $confirm = useConfirm(),
    openMode: Ref<ReplyMode> = ref(0);
let submitInfo: QuestionInfo = reactive({
  title: '',
  content: ''
});
// 编辑器关闭
const editorCloseHandler = (val) => {
      openEditor.value = val;
    },
    // 编辑器修改
    editorChangeHandler = (val) => {
      let {md} = val;
      submitInfo.content = md;
    },
    inputChangeHandler = (val) => {
      submitInfo.title = val;
    },
    editorTestValueHandler = (val) => {
      if (val) {
        $confirm.require({
          message: '检测到输入框内还有数据，是否清除？',
          header: '温馨提示',
          icon: 'pi pi-exclamation-triangle',
          accept: () => {
            submitInfo.title = '';
            submitInfo.content = '';
          },
          reject: () => {
            // submitInfo = dataUtils.replaceObj(submitInfo, '') as QuestionInfo;
          }
        });
      }
    }
/** 提问操作 */
const submitQuestion = async () => {
  // 提问
  let {title, content} = submitInfo;
  if (title.trim() !== '' && content.trim() !== '') {
    let data: QuestionInfo = {
      title,
      content: encrypt(content)
    }
    // let submit = await questionService.submit(data);
    // if (submit && submit.code === 0) {
    //   toast.success('恭喜你', '提问成功，请耐心等待吧~', 1500);
    // }
  } else {
    toast.warn('注意注意', '你有信息没填写哦，请自己检查下~', 1500);
  }
}, replyQuestion = async () => {
  // 回复
  let {content} = submitInfo;
  if (content.trim() !== '') {
    let data: AnswerReply = {
      id: Number(id),
      mode: openMode.value,
      content: encrypt(content)
    }
    let submit = await answerService.reply(data);
    if (submit && submit.code === 0) {
      toast.success('恭喜你', '回复成功，感谢您的回答~', 1500);
      openEditor.value = false;
      await getAnswerList();
    }
  } else {
    toast.warn('注意注意', '需要确确实实的发表自己的观点呢~', 1500);
  }
}
/** 发起回答 */
const replyDialog = ref(false), replyText = ref(''), atUser = ref('');
const openEditorHandler = (mode: ReplyMode) => {
      if (!validate()) return;
      openMode.value = mode;
      openEditor.value = true;
    },
    // 回复
    mainReply = (id: number, name: string) => {
      if (!validate()) return;
      replyDialog.value = true;
      atUser.value = name;
      replyId.value = id;
    },
    // 回复答案
    replyAnswer = async () => {
      if (replyText.value.trim() === '') {
        toast.warn('注意注意', '需要确确实实的发表自己的观点呢~', 1500);
        return;
      }
      let data: AnswerReply = {
        mode: 1,
        id: replyId.value,
        content: encrypt(replyText.value)
      }
      let res = await answerService.reply(data);
      if (res && res.code === 0) {
        replyDialog.value = false;
        toast.success('芜湖', '恭喜你回复成功，感谢参与谈论！(✿◡‿◡)', 1500);
        await getAnswerList();
      } else {
        toast.error('偶买噶', '不知道为何操作失败了~/(ㄒoㄒ)/~~', 1500);
      }
    },
    // 点赞答案
    kudosAction = async (data) => {
      let {execData} = data;
      if (execData) {
        let id, index;
        if ((id = execData.id)) {
          index = execData.index;
          let answer = answers.value[index];
          let opera = !answer.toOpera;
          // 记录回滚数据
          execFunction.record(answers.value);
          // 直接响应操作
          answer.toOpera = opera;
          answer.goodNumber = opera ? answer.goodNumber + 1 : answer.goodNumber - 1;
          // 监听是否需要回滚
          let rollback = await execFunction.exec(async () => {
            await answerService.kudos(id);
          });
          if (rollback) {
            // rollback 存在则直接返回记录的数据
            answers.value = rollback;
          } else {
            let title = opera ? '哇哦🤭' : '嗯哼😆', text = opera ? '感谢参与讨论哦，点赞会让更多优秀的答案被看到呢！' : '看来你也会后悔的呢~';
            if (opera) toast.success(title, text, 1500);
            else toast.warn(title, text, 1500);
          }
        }
      }
      // let execResult = execFunction.record(execData.id).exec(() => {
      //   console.log(execData.id);
      //   let a = 1 / 0;
      //   return a;
      // });
    }
</script>

<style lang="less" scoped>
.qa__title {
  font-size: 2rem;
}

.qa__info {
  width: 100vw;
}

.qa__container {
  display: flex;
  flex-wrap: wrap;
  background-color: #FDF5E6;
  margin: 0 auto;
  /* 取消 flex 间隔*/
  align-content: flex-start;
}

.answer__container {

}

.qa__update_time {
  margin-right: 15px;
  margin-bottom: 10px;
  font-size: 13px;
}

.qa__label {
  margin-right: 7px;
  color: rgb(106, 155, 124);
}

.reply__action {
  &:hover {
    cursor: pointer;
    color: var(--text-gray-color);

    svg {
      fill: var(--text-gray-color);
    }

    transition: .15s all;
  }
}

.reply__time {
  margin-left: 5px;
}

.reply__container {
  color: rgb(35, 38, 41);
  font-size: 13px;
  line-height: 18px;
  text-align: left;
  vertical-align: baseline;
}

.reply__author__link {
  color: #0a95ff
}

</style>
